#include <iostream>
#include "common.h"
#include <bitset>

using namespace std;


// bitn 置1
#define SET_BIT_N(X,N) (X | (1U << (N-1)))

// bitn 置0
#define CLEAR_BIT_N(X,N) (X & (~(1U << (N-1))))

// bitn 不变
#define SET_BIT_N_NO_CHANGE(X,N)  (X | (0U << (N - 1)))


//用宏定义将32位数x的第n位到第m位(bit0为第1位)置位
#define SET_BITS_N_M(x,n,m) (x | (((~0U)>>(32-(m-n+1)))<<(n-1)))
 
//用宏定义将32位数x的第n位到第m位(bit0为第1位)清零
#define CLEAR_BITS_N_M(x,n,m) (x & (~(((~0U)>>(32-(m-n+1)))<<(n-1))))
 
//用宏定义获取32位数x的第n位到第m位(bit0为第1位)的部分
#define GET_BITS_N_M(x,n,m) ((x & ~(~(0U)<<(m-n+1))<<(n-1))>>(n-1))

// 保留数据区的特定位
#define REMAIN_BITS_N_M(x,n,m)  (x & (((~0U) >> (32-(m-n+1))) << (n-1)))

// 求一个int类型数据的绝对值
#define GET_ABSOLUTE_VALUE(a)  ((((a)>>31)==0) ? (a) : ((~(a))+1)) 

// 判断一个整数N，是否是2的整数次幂
#define IS_2_N(N) ( (((N) & ((N)-1))==0) ? true : false )

//交换一个32位无符号数的前后16bit位
#define SWAP_A16_B16(X) (((X) >> 16) | ((X) << 16))


// 两数平均，防止溢出
inline int average1(int x, int y)
{
	return (x >> 1) + (y >> 1) + (x & y & 1);
}

inline int average2(int x, int y)
{
	return (x & y) + ((x ^ y) >> 1);
}

// 计算二进制下的1的个数
int popcount(int x)
{
	int res = 0;
	for(; x; x&=x-1) res ++;
	return res;
}

// bit位翻转
uint32_t reverse_bit(uint32_t value)
{
	uint32_t num = 0;
	int i = 0;
	for (i = 1; i < 32; i++)
	{
		num += value & 1;
		num <<= 1;
		value >>= 1;
	}
	return num;
}



int main(int argc ,char *argv[])
{

    {
        __LOG__("与 或 运算");
        int a = 5; 
        cout << bitset<32>(a) << endl;

        a = REMAIN_BITS_N_M(5,3,5);
        // SET_BIT_NO_CHANGE(a,1);

        cout << a << endl;
        cout << bitset<32>(a) << endl;


        cout << bitset<32>(0U) << endl;
        cout << bitset<32>(~(0U)) << endl;
    }

    {
        __LOG__("异或运算");

        int a = 234;//000000000000000000000000 11101010

        cout << "二进制: " << bitset<32>(a) << hex << " 十六进制: " << a << dec << " 十进制: " << a << endl;

        a = a ^ 0xff;//000000000000000000000000 00010101

        cout  << "二进制: " << bitset<32>(a) << hex << " 十六进制: " << a << dec << " 十进制: " << a << endl;
    }

    {
        __LOG__("异或运算 交换俩数");

        int a = -12;
        int b = 34;
        
        cout << "交换前: " << "a = " << a << " b= " << b << endl;

        a=a^b;
        b=a^b; // b^(a^b)
        a=a^b; // (a^b)^(b^(a^b))
        cout << "交换后: " << "a = " << a << " b= " << b << endl;
    }

    {
        __LOG__("符号取反，相反数");
        uint32_t a = 34;
        int32_t a1 = (~a)+1;

        cout << a1 << endl;

        int a3 = 9; // 
 
        cout << (a3 >> 0) << endl;
        cout << int(a3 >> 31) << endl;
    }

    {
        __LOG__("求绝对值");

        int a = -9;
        a = GET_ABSOLUTE_VALUE(3-4);

        cout << a <<endl;
    }

    {
        __LOG__("判断N是否是2的整数次幂");
        int N = 12;
        if(IS_2_N(N))
        {
            cout << N << " 是2的整数次幂" << endl;
        }
        else
        {
            cout << N << " 不是2的整数次幂" << endl;
        }  
    
    }

    {
        __LOG__("交换一个32位无符号数的前后16bit位");

        int N = 12;
        cout << bitset<32>(N) << endl;
        N = SWAP_A16_B16(N);
        cout << bitset<32>(N) << endl;
    }

    {
        __LOG__("两数平均防溢出");
        int a = 2;
        int b = 55;
        cout << "avg: " << average1(a,b) << endl;
    }

    {
        __LOG__("求数的二进制1的个数");

        int a = -1;

        cout << bitset<32>(a) << endl;
        cout << popcount(a) <<endl;
    }

    {
        __LOG__("移位实现四舍五入");

        int a = 2345;

        cout << a << endl;
        // 除以256
        a = (a+128) >> 8;
        cout << a << endl;

        unsigned int b = 2345;
        cout << b << endl;
        // 除以256
        b = (b+128) >> 8;
        cout << b << endl;
        
    }
    



    return 0;
}